package com.zf.multilang.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Component;

import java.util.Locale;

/**
 * 封装 MessageSource 工具：
 * 查找指定code时：配置的指定code是空值也算找到，没有配置指定code时才算找不到
 */
@Component
public class MessageUtils {
    private static MessageSource messageSource;

    /**
     * <pre>
     * 获取多语言信息，调用不能传递默认值的方法：
     *  找不到指定code时：
     *      1、spring.messages.use-code-as-default-message=false 时, 会抛出异常
     *      2、spring.messages.use-code-as-default-message=true 时, 会返回指定code
     * </pre>
     *
     * @param code   编码
     * @param args   参数
     * @param locale 语言
     */
    public static String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
        return messageSource.getMessage(code, args, locale);
    }

    /**
     * 获取多语言信息，调用不能传递默认值的方法：表现同 {@link MessageUtils#getMessage(String, Object[], Locale)} 方法一致
     */
    public static String getMessage(String code, Object[] args) throws NoSuchMessageException {
        return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
    }

    /**
     * 获取多语言信息，调用不能传递默认值的方法：表现同 {@link MessageUtils#getMessage(String, Object[], Locale)} 方法一致
     */
    public static String getMessage(String code, Locale locale) throws NoSuchMessageException {
        return messageSource.getMessage(code, null, locale);
    }

    /**
     * 获取多语言信息，调用不能传递默认值的方法：表现同 {@link MessageUtils#getMessage(String, Object[], Locale)} 方法一致
     */
    public static String getMessage(String code) throws NoSuchMessageException {
        return messageSource.getMessage(code, null, LocaleContextHolder.getLocale());
    }


    /**
     * <pre>
     * 获取多语言信息，调用可以传递默认值的方法：
     *  找不到指定code时：
     *      1、“如果传递的默认值!=null,则返回传递的默认值”，
     *      2、"如果传递的默认值==null 且 use-code-as-default-message=true，则返回指定code"
     *      3、"如果传递的默认值==null 且 use-code-as-default-message=false，则返回 null"
     * </pre>
     *
     * @param code           编码
     * @param args           参数
     * @param defaultMessage 找不到对应的code后返回的默认值
     * @param locale         语言
     */
    public static String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
        return messageSource.getMessage(code, args, defaultMessage, locale);
    }

    /**
     * 获取多语言信息，调用可以传递默认值的方法：表现同 {@link MessageUtils#getMessage(String, Object[], String, Locale)} 方法一致
     */
    public static String getMessage(String code, Object[] args, String defaultMessage) {
        return messageSource.getMessage(code, args, defaultMessage, LocaleContextHolder.getLocale());
    }


    /**
     * {@link MessageSourceAutoConfiguration} 类自动配置了一个 {@link MessageSource} bean，
     * 默认是 {@link ResourceBundleMessageSource} 类型
     */
    @Autowired
    public void setMessageSource(MessageSource messageSource) {
        MessageUtils.messageSource = messageSource;
    }
}
